package com.hll.javaweb.servlet.reflect_servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
// 很有意思的一个封装Servlet的类
// 之前请求一个接口，可以用action属性值来区分，通过if判断调用不同的方法，
// 如 session/SessionServlet中所示
// 如果利用反射，就可以免去 if else的判断了
public abstract class BaseServlet extends HttpServlet {
  private static final long serialVersionUID = 1L; // 建议子类都生成自己的UID

  // 子类会继承
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    // action参数就可以用来判断是当前用户模块的哪一个操作。
    String action = request.getParameter("action");
    // 定义一个Method方法对象
    Method actionMethod;
    try {
      // 通过反射获取到与action字符串对应的操作方法
      // 当子类（具体的servlet）继承时，getClass和this都是子类的类对象和实例
      // 如果子类中有与 action同名的方法时可以正确调用
      actionMethod =
          getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);
      // 调用Method对象的invoke函数执行方法
      actionMethod.invoke(this, request, response);
    } catch (NoSuchMethodException
        | SecurityException
        | IllegalAccessException
        | IllegalArgumentException
        | InvocationTargetException e) {
      e.printStackTrace();
    }
  }
}
